package com.sz.biz.logistics.serialno.utils;

import static com.sz.biz.logistics.serialno.constants.BillNumberConstants.Regexs;
import static com.sz.biz.logistics.serialno.constants.BillNumberConstants.Symbols;

/**
 * Package: com.sz.biz.logistics.channelno.utils<br>
 * Description: 解析校验规则形式字符串，生成对应的正则表达式<br>
 * @author WuHan<br>
 * @date 2017-12-07 19:21<br>
 * @serial
 * @since sys-1.1.3
 */
public class RegexAssembly {
    
    private static final StringBuilder STRING_BUILDER = new StringBuilder();
    /**
     * 校验规则形式字符串解析
     * @param pattern 校验规则形式字符串
     * @return 对应的正则表达式
     */
    public static String parseExample(String pattern) {
    
        if (!pattern.contains(
                Symbols.SYMBOL_SEPERATOR)) {
            if (!pattern.contains(
                    Symbols.SYMBOL_DIGIT)
                    && !pattern.contains(
                    Symbols.SYMBOL_LETTER)
                    && !pattern.contains(
                    Symbols.SYMBOL_MIXED)) {
                throw new IllegalArgumentException("模式串格式有误，或模式串不含可变部分！");
            }
        } else {
            return null;
        }
        
        STRING_BUILDER.append(
                Regexs.START_RESTRICTOR);
        
        replaceWithRegex(pattern);
        
        String res = STRING_BUILDER.append(
                Regexs.END_RESTRICTOR).toString();
        STRING_BUILDER.delete(0, STRING_BUILDER.length());
        return res;
    }
    
    private static void replaceWithRegex(String pattern) {
        
        //模式串后加一个空字符占位使长度+1，防止遍历时数组越界。
        pattern += " ";
        for (int i = 0, count = 1; i < pattern.length() - 1; i++) {
            if (pattern.substring(i, i + 1).matches(
                    Regexs.MIXED_CHARACTER)) {
                STRING_BUILDER.append(pattern.substring(i, i + 1));
            } else {
                //这里使用了i+1的偏移量，所以前面pattern长度要+1
                if (pattern.substring(i, i + 1)
                           .equals(pattern.substring(i + 1, i + 2))) {
                    count++;
                } else {
                    switch (pattern.substring(i, i + 1)) {
                        case Symbols.SYMBOL_DIGIT:
                            STRING_BUILDER.append(
                                    Regexs.PURE_DIGIT)
                                          .append(Regexs.OPENING_RANGE_BRACKET)
                                          .append(count)
                                          .append(Regexs.CLOSING_RANGE_BRACKET);
                            count = 1;
                            break;
                        case Symbols.SYMBOL_LETTER:
                            STRING_BUILDER.append(
                                    Regexs.PURE_LETTER)
                                          .append(Regexs.OPENING_RANGE_BRACKET)
                                          .append(count)
                                          .append(Regexs.CLOSING_RANGE_BRACKET);
                            count = 1;
                            break;
                        case Symbols.SYMBOL_MIXED:
                            STRING_BUILDER.append(
                                    Regexs.MIXED_CHARACTER)
                                          .append(Regexs.OPENING_RANGE_BRACKET)
                                          .append(count)
                                          .append(Regexs.CLOSING_RANGE_BRACKET);
                            count = 1;
                            break;
                        case Symbols.SYMBOL_VERIFYCODE:
                            count = 1;
                            STRING_BUILDER.append(
                                    Regexs.DOUBLE_SLASH)
                                          .append(Symbols.SYMBOL_VERIFYCODE)
                                          .append(Regexs.OPENING_RANGE_BRACKET)
                                          .append(count)
                                          .append(Regexs.CLOSING_RANGE_BRACKET);
                            break;
                        default:
                            break;
                    }
                }
            }
        }
    }
}
